programming4us
           
 
 
Programming

Programming WCF Services : Queued Services - Delivery Failures (part 2) - Processing the Dead-Letter Queue

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
9/7/2011 11:27:18 AM

4. Processing the Dead-Letter Queue

The client needs to somehow process the accumulated messages in the DLQ. In the case of the system-wide DLQ, the client can provide a mega-service that supports all contracts of all queued endpoints on the system to enable it to process all failed messages. This is clearly an impractical idea, though, because that service could not possibly know about all queued contracts, let alone provide meaningful processing for all applications. The only feasible way to make this solution work would be to restrict the client side to at most a single queued service per system. Alternatively, you can write a custom application for direct administration and manipulation of the system DLQ using the types in System.Messaging. That application will parse and extract the relevant messages and process them. The problem with that approach (besides the inordinate amount of work involved) is that if the messages are protected and encrypted (as they should be), the application will have a hard time dealing with and distinguishing between them. In practical terms, the only possible solution for a general client-side environment is the one offered by MSMQ 4.0: a custom DLQ. When using a custom DLQ, you also provide a client-side service whose queue is the application’s custom DLQ. That service will process the failed messages according to the application-specific requirements.

4.1. Defining the DLQ service

Implementing the DLQ service is done like any other queued service. The only requirement is that the DLQ service be polymorphic with the original service’s contract. If multiple queued endpoints are involved, you will need a DLQ per contract per endpoint. Example 2 shows a possible setup.

Example 2. DLQ service config file
<!-- Client side -->
<system.serviceModel>
<client>
<endpoint
address = "net.msmq://localhost/private/MyServiceQueue"
binding = "netMsmqBinding"
bindingConfiguration = "MyCustomDLQ"
contract = "IMyContract"
/>
</client>
<bindings>
<netMsmqBinding>
<binding name = "MyCustomDLQ"
deadLetterQueue = "Custom"
customDeadLetterQueue = "net.msmq://localhost/private/MyCustomDLQ">
</binding>
</netMsmqBinding>
</bindings>
</system.serviceModel>

<!-- DLQ service side -->
<system.serviceModel>
<services>
<service name = "MyDLQService">
<endpoint
address = "net.msmq://localhost/private/MyCustomDLQ"
binding = "netMsmqBinding"
contract = "IMyContract"
/>
</service>
</services>
</system.serviceModel>


The client config file defines a queued endpoint with the IMyContract contract. The client uses a custom binding section to define the address of the custom DLQ. A separate queued service (potentially on a separate machine) also supports the IMyContract contract. The DLQ service uses as its address the DLQ defined by the client.

4.2. Failure properties

The DLQ service typically needs to know why the queued call delivery failed. WCF therefore offers the MsmqMessageProperty class, used to find out the cause of the failure and the current status of the message. MsmqMessageProperty is defined in the System.ServiceModel.Channels namespace:

public sealed class MsmqMessageProperty
{
public const string Name = "MsmqMessageProperty";

public int AbortCount
{get;}
public DeliveryFailure? DeliveryFailure
{get;}
public DeliveryStatus? DeliveryStatus
{get;}
public int MoveCount
{get;}
//More members
}

The DLQ service needs to obtain the MsmqMessageProperty from the operation context’s incoming message properties:

public sealed class OperationContext : ...
{
public MessageProperties IncomingMessageProperties
{get;}
//More members
}
public sealed class MessageProperties : IDictionary<string,object>,...
{
public object this[string name]
{get;set;}
//More members
}

When a message is passed to the DLQ, WCF will add to its properties an instance of MsmqMessageProperty detailing the failure. MessageProperties is merely a collection of message properties that you can access using a string as a key. To obtain the MsmqMessageProperty, use the constant MsmqMessageProperty.Name, as shown in Example 3.

Example 3. Obtaining the MsmqMessageProperty
[ServiceContract(SessionMode = SessionMode.NotAllowed)]
interface IMyContract
{
[OperationContract(IsOneWay = true)]
void MyMethod(string someValue);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class MyDLQService : IMyContract
{
[OperationBehavior(TransactionScopeRequired = true)]
public void MyMethod()
{
MsmqMessageProperty msmqProperty = OperationContext.Current.
IncomingMessageProperties[MsmqMessageProperty.Name] as MsmqMessageProperty;

Debug.Assert(msmqProperty != null);
//Process msmqProperty
}
}


Note in Example 3 the use of the practices discussed so far for configuring the session mode, instance management, and transactions—the DLQ service is, after all, just another queued service.

The properties of MsmqMessageProperty detail the reasons for failure and offer some contextual information. MoveCount is the number of attempts made to play the message to the service, and AbortCount is the number of attempts made to read the message from the queue. AbortCount is less relevant to recovery attempts, because it falls under the responsibility of MSMQ and usually is of no concern. DeliveryStatus is a nullable enum of the type DeliveryStatus, defined as:

public enum DeliveryStatus
{
InDoubt,
NotDelivered
}

When a regular WCF queued service processes a delivered call, DeliveryStatus is set to null. With a DLQ service, DeliveryStatus will be set to DeliveryStatus.InDoubt unless the message was positively not delivered (i.e., a NACK was received). For example, expired messages are considered in-doubt because their time to live elapsed before the service could acknowledge them one way or the other.

The DeliveryFailure property is a nullable enum of the type DeliveryFailure, defined as follows (without the specific numerical values):

public enum DeliveryFailure
{
AccessDenied,
NotTransactionalMessage,
Purged,
QueueExceedMaximumSize,
ReachQueueTimeout,
ReceiveTimeout,
Unknown
//More members
}


Note:

When a regular WCF queued service processes a queued call and access MsmqMessageProperty, both DeliveryStatus and DeliveryFailure are set to null.


4.3. Implementing a DLQ service

The DLQ service cannot affect a message’s properties (for example, extending its time to live). Handling of delivery failures typically involves some kind of compensating workflow: notifying the administrator; trying to resend a new message, or resending a new request with extended timeout; logging the error; or perhaps doing nothing (i.e., merely processing the failed call and returning, thus discarding the message).

Example 4 demonstrates a possible DLQ service implementation.

Example 4. Implementing a DLQ service
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class MyDLQService : IMyContract
{
[OperationBehavior(TransactionScopeRequired = true)]
public void MyMethod(string someValue)
{
MsmqMessageProperty msmqProperty = OperationContext.Current.
IncomingMessageProperties[MsmqMessageProperty.Name] as MsmqMessageProperty;
//If tried more than 25 times: discard message
if(msmqProperty.MoveCount >= 25)
{
return;
}
//If timed out: try again
if(msmqProperty.DeliveryStatus == DeliveryStatus.InDoubt)
{
if(msmqProperty.DeliveryFailure == DeliveryFailure.ReceiveTimeout)
{
MyContractClient proxy = new MyContractClient();
proxy.MyMethod(someValue);
proxy.Close();
}
return;
}
if(msmqProperty.DeliveryStatus == DeliveryStatus.InDoubt ||
msmqProperty.DeliveryFailure == DeliveryFailure.Unknown)
{
NotifyAdmin();
}
}
void NotifyAdmin()
{...}
}



The DLQ service in Example 4 examines the cause of the failure. If WCF has tried more than 25 times to deliver the message, the DLQ service simply gives up and drops the message. If the cause for the failure was a timeout, the DLQ service tries again by creating a proxy to the queued service and calling it, passing the same arguments from the original call (the in-parameters to the DLQ service operation). If the message is in-doubt or an unknown failure took place, the service notifies the application administrator.
Other -----------------
- Parallel Programming with Microsoft Visual Studio 2010 : Task Parallelism - Cancellation
- Parallel Programming with Microsoft Visual Studio 2010 : Task Parallelism - Sort Examples
- jQuery 1.3 : DOM Manipulation - Wrapping elements & Copying elements
- iOS SDK : Debugging (part 4) - Instruments—Leaks
- iOS SDK : Debugging (part 3) - NSZombieEnabled
- iOS SDK : Debugging (part 2) - Watchpoints
- iOS SDK : Debugging (part1 )
- iOS SDK : Installing Applications on an iPhone
- Software Testing with Visual Studio Team System 2008 : Web Testing - Recording a test
- Software Testing with Visual Studio Team System 2008 : Unit testing web services & Code coverage unit test
- .NET Debugging : Introduction to the Tools - SOS & SOSEX
- .NET Debugging : CLR 4.0 - Synchronization & Interoperability
- iPhone Programming : Connecting to the Network - Getting Data from the Internet
- iPhone Programming : Connecting to the Network - Sending Email
- Programming Excel with VBA and .NET : Tasks in Visual Basic - Check Results
- Programming Excel with VBA and .NET : Tasks in Visual Basic - Read and Write Files
- Programming Excel with VBA and .NET : Tasks in Visual Basic - Get Dates and Times
- Programming Excel with VBA and .NET : Tasks in Visual Basic - Work with Text
- A Technical Overview of the Mobile Web : THE TECHNICAL CHALLENGES OF MOBILE DEVICES (part 2)
- A Technical Overview of the Mobile Web : THE TECHNICAL CHALLENGES OF MOBILE DEVICES (part 1) - Physical Constraints
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us